<!--
 * @Author: zhangjingyu
 * @Date: 2021-04-16 14:57:48
 * @LastEditors: zhangjingyu
 * @LastEditTime: 2021-04-26 17:55:08
 * @FilePath: \vprisk10.14\src\components\vprisk-grid\VpriskGrid.vue
 * @Description: 按钮结合表格组件
-->
<template>
  <div>
    <upper-template
      ref="upper"
      v-bind="{ ...$props, ...$attrs }"
      v-on="$listeners"
      :configIcon="configIcon"
      @search="(searchForm.page = 1), searchFunc()"
      @clear="clearSearch()"
    >
      <!-- 插槽嵌套 -->
      <!-- 操作按钮区 -->
      <slot slot="buttonArea" name="button" ></slot>
      <!-- 导出操作区域 -->
      <slot slot="exportArea" name="export"></slot>
      <!-- 导入操作区域 -->
      <slot slot="importArea" name="import"></slot>
      <!-- 搜索区域 -->
      <slot slot="searchArea" name="search"> </slot>
      <!-- 列表显示隐藏操作区 -->
      <div slot="columnHide">
        <slot name="colHide"> </slot>
      </div>
    </upper-template>
    <el-table
      v-bind="{ ...$props, ...$attrs }"
      v-on="$listeners"
      ref="table"
      :data="data"
      @row-click="rowClick"
    >
      <slot name="col"></slot>
    </el-table>
    <!-- 分页 -->
    <pagination
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
      @refresh="searchFunc"
      :current-page="searchForm.page"
      :page-size="searchForm.size"
      :total="total"
    ></pagination>
    <!-- 新增 编辑弹窗 -->
    <el-dialog
      v-dialogDrag
      :title="dialogTitle"
      :visible.sync="addOrEditShow"
      :width="dialogWidth"
    >
      <div ref="saveFormCom">
        <!-- 弹窗主体部分 -->
        <slot name="dialogBody"> </slot>
      </div>
      <div slot="footer">
        <template v-if="useFooterBtn">
          <el-button @click="saveFunc" v-if="saveFlgCom != 3">确 定</el-button>
          <el-button @click="addOrEditShow = false">取 消</el-button>
        </template>
        <slot name="footerBtn" v-if="!useFooterBtn"> </slot>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import http from "@/api/config";
import vpToolbar from "./VpToolbar";
export default {
  name: "vprisk-grid",
  components: { vpToolbar },
  props: {
    url: { type: String, default: "" },
    gridRequestMethod: { type: String, default: "post" },
    searchForm: {
      type: Object,
      default: () => ({ page: 1, size: 15 })
    },
    saveForm: {
      type: Object,
      default: () => ({})
    },
    dataPath: { type: String, default: "res.datas.rows" },
    totalPath: { type: String, default: "res.datas.total" },
    dialogWidth: { type: [String, Number], default: "514px" },
    addOrEdit: { type: Boolean, defalut: false },
    configIcon: { type: Boolean, default: false },
    saveFlg: { type: [String, Number], default: "1" }
  },
  data() {
    return {
      data: [],
      total: 0,
      addOrEditShow: this.addOrEdit,
      buttonInfo: {}, //当前点击按钮信息
      dialogTitle: "",
      saveFlgCom: this.saveFlg,
      useFooterBtn: true // 是否使用弹窗的底部按钮
    };
  },
  watch: {
    addOrEdit(n, o) {
      this.addOrEditShow = n;
    },
    addOrEditShow(n, o) {
      this.$emit("update:addOrEdit", n);
    },
    saveFlg(n, o) {
      this.saveFlgCom = n;
    },
    saveFlgCom(n, o) {
      this.$emit("update:saveFlg", n);
    }
  },
  computed: {
    selection() {
      if (this.$refs.table) {
        return this.$refs.table.selection;
      } else {
        return [];
      }
    }
  },
  created() {
    this.searchFunc();
  },
  mounted() {
    this.eventListener(); // 添加按钮监听
    this.initTableMethods();// 基础e-table所有方法
  },
  methods: {
    rowClick(row) {
      this.$refs.table.clearSelection();
      this.$refs.table.toggleRowSelection(row, true);
      this.$emit("rowClick", row);
    },
    async clearSearch() {
      await this.$emit("beforeClearSearch", this.searchForm);
      for (const key in this.searchForm) {
        if (key !== "page" && key != "size") {
          const element = object[key];
        }
      }
      console.log(this.searchForm, "hou");
      await this.$emit("afterClearSearch", this.searchForm);
    },
    async searchFunc() {
      await this.$emit("beforeLoad", this.searchForm);
      await http[this.gridRequestMethod](this.url, this.searchForm).then(
        res => {
          if (res.code == 200) {
            this.data = eval(this.dataPath);
            this.total = eval(this.totalPath);
            this.$emit("afterLoad", res);
          }
        }
      );
    },
    // 表格内置请求方法
    request(url, data, methodType = "post") {
      return http[methodType](url, data);
    },
    // 监听事件总线上的按钮事件
    eventListener() {
      // 先注销再绑定
      this.bus.$off("vpToolbarAction");
      this.bus.$on("vpToolbarAction", val => {
        // 传入按钮信息
        this.action(val);
      });
    },
    async action(val) {
      //  若不使用这里的操作逻辑，传入noAction为true，在外部自己写逻辑即可
      if (val.noAction) return;
      this.buttonInfo = val;
      this.dialogTitle = val.dialogTitle; // 更新弹窗title
      this.useFooterBtn = val.useFooterBtn; // 是否使用本页面弹窗底部按钮
      // 按钮点击判断处理逻辑
      console.log(val, "按钮判断逻辑");
      if (val.type === "add") {
        // 新增
        this.addFunc(val);
      }
      if (val.type === "edit") {
        // 编辑
        this.editFunc(val);
      }
      if (
        val.type === "delete" ||
        val.type === "lock" ||
        val.type === "unlock" ||
        val.type === "start" ||
        val.type === "stop"
      ) {
        // 改变状态一类
        this.changeStatusFunc(val);
      }
      if (val.type === "view") {
        // 查看
        this.viewFunc(val);
      }
    },
    addFunc(val) {
      // 这里是基础弹出窗逻辑，其他业务逻辑在按钮的action事件里写入
      if (val.useInterFunc) {
        this.saveFlgCom = 1;
        for (const key in this.saveForm) {
          this.saveForm[key] = "";
        }
        this.addOrEditShow = true;
      }
    },
    editFunc(val) {
      // 这里是简单弹出窗编辑逻辑，个性化复杂逻辑在按钮的action事件里写入
      if (val.useInterFunc) {
        // 常规方法
        this.saveFlgCom = 2;
        let selection = this.$refs["table"].selection;
        if (selection.length != 1)
          return this.$message.warning("请选择一条数据编辑");
        for (const key in selection[0]) {
          this.saveForm[key] = selection[0][key];
        }
        this.addOrEditShow = true;
      }
    },
    viewFunc(val) {
      // 这里是简单查看逻辑，个性化复杂逻辑在按钮的action事件里写入
      if (val.useInterFunc) {
        // 常规方法
        this.saveFlgCom = 3;
        let selection = this.$refs["table"].selection;
        if (selection.length != 1)
          return this.$message.warning("请选择一条数据查看");
        for (const key in selection[0]) {
          this.saveForm[key] = selection[0][key];
        }
        this.addOrEditShow = true;
      }
    },
    // 删除 锁定 解锁 启动 停用 等 默认传{ids:['id','id','id',...]}
    changeStatusFunc(val) {
      // console.log(val)
      if (val.useInterFunc) {
        let selection = this.$refs["table"].selection;
        if (selection.length < 1) {
          return this.$message.warning(`请选择要${val.text}的用户`);
        }
        this.$confirm(
          `您确定要${val.text}选中项吗？`,
          `${val.dialogTitle || val.text || "提示"}`,
          {
            confirmButtonText: "确定",
            cancelButtonText: "取消",
            type: "warning"
          }
        )
          .then(() => {
            //传入字段支持object.key.key形式
            let fieldPath = val.idField.split("."),
              idstr = "";
            fieldPath.forEach(item => {
              idstr += `["${item}"]`;
            });
            console.log(idstr);
            let ids = selection.map(v => {
              return eval("v" + idstr) || v.id;
            });
            this.request(val.url, { ids }, val.requestMethod).then(res => {
              if (res.code == 200) {
                this.$message.success(val.text + "成功");
                this.searchFunc();
              } else {
                this.$message.error(res.message);
              }
            });
          })
          .catch(err => {
            console.log(err);
            this.$message({
              type: "info",
              message: "已取消" + val.text
            });
          });
      }
    },
    saveFunc() {
      this.$emit("saveFunc", this.buttonInfo);
    },

    handleSizeChange(val) {
      this.searchForm.size = val;
      this.searchFunc();
    },
    handleCurrentChange(val) {
      this.searchForm.page = val;
      this.searchFunc();
    },
    reload() {
      this.searchFunc();
    },
    initTableMethods(){
      let arr =  [
        'clearSelection',
        'toggleRowSelection',
        'toggleAllSelection',
        'toggleRowExpansion',
        'setCurrentRow',
        'clearSort',
        'clearFilter',
        'doLayout',
        'sort' 
      ],tb = this.$refs.table;
     arr.forEach(item=>{
       this[item] = tb[item]
     })
    },
  },
  beforeDestroy() {
    this.bus.$off("vpToolbarAction");
  }
};
</script>

<style lang="scss" scoped>
</style>
